package com.java80.littlegame.common.base;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hazelcast.cluster.MemberAttributeOperationType;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.Member;
import com.hazelcast.core.MemberAttributeEvent;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
import com.java80.littlegame.common.utils.GsonUtil;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.eventbus.EventBus;

public abstract class BaseVerticle extends AbstractVerticle {
	final transient static Logger log = LoggerFactory.getLogger(BaseVerticle.class);

	@Override
	public void start() throws Exception {
		super.start();
		SystemDataMgr.loadSystemData();
		EventBus eventBus = vertx.eventBus();
		vertx.deployVerticle(VertxMessageHelper.class, new DeploymentOptions().setWorker(true).setInstances(3));
		// eventBus.registerDefaultCodec(BaseMsg.class, new VertxMsgCodec());
		String queueName = queueName();
		if (StringUtils.isNotBlank(queueName)) {
			eventBus.consumer(queueName, msg -> {
				String json = msg.body().toString();
				log.info("收到来自集群的消息：->{}", json);
				BaseHandler.addTask(getHandler(), json);
			});
		}

		if (needPublishServiceStatus()) {
			publishService();
		}
	}

	protected void publishService() {

		// 发布服务信息
		ServiceStatus ss = getServiceStatus();
		HazelcastInstance ins = Hazelcast.getHazelcastInstanceByName(ss.getInstanceName());
		// 获取其他服务的信息缓存到本地
		Set<Member> members = ins.getCluster().getMembers();
		for (Member member : members) {
			if (member.localMember()) {
				member.setStringAttribute(ss.getServiceId(), GsonUtil.parseObject(getServiceStatus()));
			} else {
				Map<String, Object> attributes = member.getAttributes();
				for (Entry<String, Object> entry : attributes.entrySet()) {
					ServiceStatus parseJson = GsonUtil.parseJson(entry.getValue().toString(), ServiceStatus.class);
					ServiceStatusHelper.addServiceStatus(parseJson);
				}
			}
		}
		ins.getCluster().addMembershipListener(new MembershipListener() {

			@Override
			public void memberRemoved(MembershipEvent membershipEvent) {
				if (membershipEvent.getMember().localMember()) {
					log.info("关闭本节点！");
				}
				if (!membershipEvent.getMember().localMember()) {
					Member member = membershipEvent.getMember();
					log.info("集群中节点关闭！" + member);
					Map<String, Object> attributes = member.getAttributes();
					for (Entry<String, Object> ent : attributes.entrySet()) {
						ServiceStatusHelper.removeServiceStatus(ent.getKey());
					}
				}
			}

			@Override
			public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) {
				System.out.println("节点发生改变。。。。");
				Member member = memberAttributeEvent.getMember();
				if (!member.localMember()) {
					String key = memberAttributeEvent.getKey();
					if (memberAttributeEvent.getOperationType() == MemberAttributeOperationType.PUT) {
						String attr = member.getStringAttribute(key);
						ServiceStatus parseJson = GsonUtil.parseJson(attr, ServiceStatus.class);
						ServiceStatusHelper.addServiceStatus(parseJson);

					} else if (memberAttributeEvent.getOperationType() == MemberAttributeOperationType.REMOVE) {
						ServiceStatusHelper.removeServiceStatus(key);
					}
				}
			}

			@Override
			public void memberAdded(MembershipEvent membershipEvent) {
			}
		});

	}

	@Override
	public void stop() throws Exception {
		super.stop();

	}

	public abstract String queueName();

	public abstract BaseHandler getHandler();

	public abstract ServiceStatus getServiceStatus();

	public abstract boolean needPublishServiceStatus();
}
